<template>
  <BasicDrawer
    v-bind="$attrs"
    :title="getTitle"
    @register="registerDrawer"
    @close="handleClose"
    :showFooter="false"
    destroyOnClose
    placement="top" 
    height="100%"
    :get-container="false"
  >
    <div>
      <BasicTable @register="registerTable">
        <template #cmd="{record}">
            <ASelect v-model:value="record['cmd']" :options="debugModel.deviceTypeId != 10 ? CmdOptions : CmdCusOptions" style="width: 100%" />
        </template>
        <template #start="{record}">
          <AInputNumber v-model:value="record['start']" :min="0" step="1" :max="65535"/>
        </template>
        <template #type="{record}">
          <AInput v-model:value="record['writeValue']" placeholder="写值">
          <template #addonBefore>
            <ASelect v-model:value="record['type']" :options="TypeOptions" style="width: 86px;" />
          </template>
          </AInput>
        </template>
        <template #message="{record}">
          <AInput v-model:value="record['message']" :allowClear="true"/>
        </template>
        <template #action="{ record }">
          <TableAction :actions="getActions(record)" />
        </template>
      </BasicTable>
    </div>
    <div style="padding: 5px 18px">
      <AButton type="primary" @click="() => debugInfo.length = 0">清除</AButton>
    </div>
    <div style="padding: 5px 18px">
      <div style="height: 220px; border: 1px solid #e3e3e3; overflow-y: auto">
        <template v-for="debug in debugInfo">
          <div style="margin: 3px 0px 6px">
            <a-row class="u-debug-desc">
              <a-col span="8" style="text-align: left">
                <span v-if="debug['code'] == 200" style="color: green">
                  [状态]&nbsp;成功
                </span>
                <span v-else style="color: #d4380d">
                  [状态]&nbsp;{{debug['message']}}
                </span>
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                <span v-show="debugModel.deviceTypeId != 10">
                  <label>[{{getValueDesc(debug['data'])}}] =</label>&nbsp;{{debug['data']['value']}}
                </span>
              </a-col>
              <a-col span="8" style="text-align: center;">
                <span style="color: #cc8500">
                  [指令]&nbsp;{{debug['data']['model']['cmd']}}
                </span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                <span>
                  [耗时] <label>{{debug['data']['respTime'] - debug['data']['reqTime']}}ms</label>
                </span>
              </a-col>
              <a-col span="8" style="text-align: right">
                <span>
                  [DTU编号] <label>{{debug['data']['model']['deviceSn']}}</label>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                  [设备地址] <label>{{debug['data']['model']['childSn']}}</label>
                </span>
              </a-col>
            </a-row>
            <div class="u-debug-desc">
              <label>[{{getTime(debug['data']['reqTime'])}}][请求报文]</label><span class="u-debug-msg">{{debug['data']['reqMsg']}}</span>
            </div>
            <div class="u-debug-desc">
              <label>[{{getTime(debug['data']['respTime'])}}][响应报文]</label><span class="u-debug-msg">{{debug['data']['respMsg']}}</span>
            </div>
          </div>
        </template>
      </div>
    </div>
  </BasicDrawer>
</template>
<script lang="ts" setup>
  import { defineComponent, ref, computed, unref, useAttrs } from 'vue';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { BasicTable, TableAction, ActionItem } from '/@/components/Table';
  import { useListPage } from '/@/hooks/system/useListPage';
  import { DebugWebsocket } from "../debug/debugUtils";
  import { debugColumns, searchDebugFormSchema, ProtocolType, CmdOptions, TypeOptions, CmdCusOptions, rtuId } from './modbus.data';
  import { list } from '../deviceChild/deviceChild.api';
  import { getSerialByCom } from '../serial/serial.api';
  import { useMessage } from '/@/hooks/web/useMessage';

  const { createMessage: $message } = useMessage();
  
   /**
   * @type {WebSocket}
   */
  let debugWebsocket = ref();

  const editModel = ref({});
  const searchModel = ref({});
  const debugInfo = ref([]);
  const debugModel = ref({deviceSn: null, deviceTypeId: null});
  const debugSearchModel = ref({uid: null});
  const childSearchModel = ref({uid: null});
  const childModel = ref({deviceSn: null, name: '', uid: null});

  const debugCusColumns = ref([]);

  const labelCol = { style: { width: '150px' } };
  const wrapperCol = { span: 18 };

  //初始化
  const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
    debugModel.value = data.record;
    debugSearchModel.value.uid = data.record.uid;
    if(data.record.deviceTypeId == 10) {
      debugCusColumns.value = debugColumns.splice(3, 2);
    } else {
      if(debugColumns.length == 5) {
        debugColumns.splice(3, 0, ...debugCusColumns.value)
      }
    }
    /**
     * @type {DebugWebsocket}
     */
     debugWebsocket.value = new DebugWebsocket('dtu', (data) => {
        debugInfo.value.push(data);
    });
  });

  const getTitle = computed(() => "MODBUS设备调试" + "(" + debugModel.value.deviceSn + ")" );


  // 列表页面公共参数、方法
  const { tableContext } = useListPage({
    designScope: 'iot-modbus-debug-template',
    tableProps: {
      title: '',
      api: list,
      columns: debugColumns,
      showIndexColumn: false,
      showTableSetting: false,
      tableSetting: { fullScreen: true },
      pagination: false, 
      actionColumn: {
        width: 40,
        title: '操作',
        dataIndex: 'action',
        slots: { customRender: 'action' },
      },
      formConfig: {
        schemas: searchDebugFormSchema,
      },
      beforeFetch(params) {
        params.uid = debugSearchModel.value.uid;
      },
    },
  });

  const [registerTable] = tableContext;


  /**
   * 操作列定义
   * @param record
   */
   function getActions(record) {
    return [
      {
        label: '发送',
        onClick: debugSend.bind(null, record),
      },
    ];
  }

  function getTime(time) {
    let date = new Date(time);
    return date.getHours()+":"+date.getMinutes()+":"+date.getSeconds();
  };

  function getValueDesc({model}) {
    let cmd = parseInt(model['cmd']);
    if(isNaN(cmd)) {
      return cmd == 'read' ? ('读') : cmd == 'write' ? '写' : '异步写';
    } else {
      return cmd <=4 ? ('读' + model.type + "值") : ('写' + model.type + "值");
    }
  }

  async function debugSend(value) {
    let record = Object.assign({}, value);
    record['host'] = debugModel.value.ip;
    record['port'] = debugModel.value.port;
    record['deviceSn'] = debugModel.value.deviceSn;
    let deviceTypeId = debugModel.value.deviceTypeId;
    record['protocolType'] = deviceTypeId == rtuId ? 'rtu' : 'tcp';
    if(record['protocolType'] == 'rtu') {
      const res = await getSerialByCom(record['deviceSn']);
      if(res.success){
        record['baudRate'] = data['baudRate'];
        record['dataBits'] = data['dataBits'];
        record['parity'] = data['parity'];
        record['stopBits'] = data['stopBits'];
        debugWebsocket.value.debug(record);
      }else{
        $message.error("串口不存在["+debugModel.value.deviceSn+"]")
      }
    } else {
      debugWebsocket.value.debug(record);
    }
  }

  function handleClose(){
    try{
      debugWebsocket.value.close();
    }catch(e){

    }
  }

</script>
<style scoped>
.u-debug-desc {
  position: relative;
  margin: 0px 16px;
}
.u-debug-msg {
  margin: 0px 5px;
}
.u-debug-col {
  margin: 3px 8px;
  display: inline-block;
}
.u-debug-col.left {
  float: left;
}
.u-debug-col.right {
  float: right;
}
.u-debug-status {
  margin-left: 3px;
}
</style>